package com.roc.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.roc.bean.TermBean;
import com.roc.dao.DaoException;
import com.roc.dao.IBaseDao;
import com.roc.dao.IMerchantDao;
import com.roc.dao.ISQLBaseDao;
import com.roc.dao.ITerminalDao;
import com.roc.pojo.Estidinfo;
import com.roc.pojo.Operators;
import com.roc.pojo.TPosAgent;
import com.roc.pojo.TPosInfo;
import com.roc.pojo.TPosReplace;
import com.roc.pojo.TblDictionaryItem;
import com.roc.pojo.TblDictionaryLayerItem;
import com.roc.pojo.TblMchtInf;
import com.roc.pojo.TblTermInf;
import com.roc.pojo.TermInfo;
import com.roc.pojo.TermInfoTmp;
import com.roc.pojo.Termapply;
import com.roc.pojo.TidRecord;
import com.roc.pojo.YjPosAgent;
import com.roc.pojo.YjPosInfo;
import com.roc.pojo.YjSnInfo;
import com.roc.service.ITerminalService;
import com.roc.service.ServiceException;
import com.roc.service.operator.IPowerInfoService;
import com.roc.util.Constance;
import com.roc.util.DateTime;
import com.roc.util.Utils;
import com.roc.util.constant.ConfigMerinfoUtil;
import com.roc.util.constant.Constant;
import com.roc.util.constant.MerchantStatus;
import com.roc.util.constant.Role;
import com.roc.util.constant.SysLogType;
import com.roc.util.constant.Terminal;
import com.roc.util.constant.TerminalBrandTek;
import com.roc.util.constant.TerminalFlag;

/**
 * 
 * @author 陈锴
 * 
 * 终端管理
 * 
 * 2014-08-13
 *
 */

@Service
@Transactional
@SuppressWarnings("all")
public class TerminalServiceImpl  implements ITerminalService {
	
	static Logger logger=LogManager.getLogger(TerminalServiceImpl.class);
	
	@Autowired
	private ITerminalDao terminalDao;
	@Autowired
	private IMerchantDao merchantDao;
	
	@Autowired
	private ISQLBaseDao sqlBaseDao;
	
	@Autowired
	private IBaseDao baseDao;
	
	@Autowired
	IPowerInfoService powerInfoService;

	@Override
	public Termapply queryTerminal(long id) throws ServiceException {
	    Termapply term=new Termapply();
		
		try {
			term=terminalDao.queryTermapplyId(id);
		} catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("查询终端申请对象出错！");
		}
	     
		return term;
	}

	@Override
	//终端添加
	public  synchronized void saveTerminal(List<TermBean> termBeanList,String account,String mid)
			throws ServiceException {
		
		try {
			int termCount=0;  //本次添加的终端数量
			for (TermBean term : termBeanList) {
				if(term == null) continue;
				//添加终端信息表
				Estidinfo estid=new Estidinfo();
				estid.setMid(mid);
				int maxTid=terminalDao.queryMaxTermapply();
				if(maxTid >= 99999999){
					throw new ServiceException("终端号已达到最大！");
				}
				terminalDao.editTermTid(maxTid+1);
				String maxNo=Constance.fillTo8(maxTid, 8);
				estid.setTid(maxNo);
				estid.setTidKind(term.getTidKind());
				estid.setPinFmt(Terminal.PIN_FMT_TWO.getCode());
				estid.setFlag(TerminalFlag.FLAG_TWO.getCode());
				estid.setEncMethod("0");
				estid.setMacAlg("0");
				estid.setBatchNo("0");
				estid.setSekIdx("0");
				estid.setSeitStatus("0");
				estid.setLogonStatus("0");
				
				terminalDao.editSave(estid);
				
				/**添加终端关联表**/
				TermInfo ter=new TermInfo();
				ter.setTermAddr(term.getTermAddress());
				ter.setTermId(maxNo);
				ter.setTerminalName(term.getTermName());
				ter.setNote(term.getTermNote());
				ter.setSerialNum(ter.getSerialNum());
				terminalDao.editSave(ter);
				
				termCount++;  //添加完成，终端数量++
				
				/**添加终端记录日志**/
				baseDao.addSyslog(SysLogType.TERM_ADD.getCode(), SysLogType.TERM_ADD.getName(), account, "操作员"+account+"添加终端成功，终端号【"+maxNo+"】");
			}
			
			//修改该申请表
			/*Termapply ter=terminalDao.queryTermapplyId(termapply.getId());
			ter.setTermInstalled(termCount+ter.getTermInstalled());
			
			editUpdate(ter);*/
			
			
		} catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("添加终端出错！");
		}
		
	}

	@Override
	//终端流水号绑定
	public void bindingTerminalSn(YjPosInfo yjPos,String accountNo) throws ServiceException {
		
		
		
		try {
			TermInfo terminfo=terminalDao.querTermInfo(yjPos.getTermCode());
			
			if(terminfo.getInstallStatus().equals("Y")){
				throw new ServiceException("终端【"+terminfo.getTermId()+"】流水号已绑定！");
			}
			
			terminfo.setInstallStatus("Y");
			
			baseDao.editUpdate(terminfo);
			
			YjPosInfo yjPosInfo=terminalDao.queryYjPosInfo(yjPos.getSerialNum(),yjPos.getPosBrand());
			
			yjPosInfo.setMercCode(yjPos.getMercCode());
			yjPosInfo.setTermCode(yjPos.getTermCode());
			yjPosInfo.setIsBind("Y");
			
			baseDao.editUpdate(yjPosInfo);
			
			
			baseDao.addSyslog(SysLogType.TERM_SUM.getCode(), SysLogType.TERM_SUM.getName(), accountNo, "操作员"+accountNo+"绑定终端流水号成功，终端号【"+yjPos.getTermCode()+"】,流水号【"+yjPos.getSerialNum()+"】");
		} catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("查询终端流水号对象出错！");
		}
		
	}

	@Override
	public List<TermBean> queryByMid(String merchantNo)
			throws ServiceException {
	
		List<TermBean> obj=null;
		try {
			obj= terminalDao.queryTerByMid(merchantNo);
		} catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("查询终端出错！");
		}
		return obj;
	}

	@Override
	public TermInfo queryTermInfo(String tid) throws ServiceException {
		TermInfo terminfo=new TermInfo();
		
		try {
			terminfo=terminalDao.querTermInfo(tid);
			terminfo.setEstidinfo(terminalDao.queryEstidinfo(tid));
			terminfo.setTermFlag(TerminalFlag.valueOfCode(terminfo.getEstidinfo().getFlag()).getName());
		} catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("查询终端流信息关联表出错！");
		}
		
		return terminfo;
	}

	@Override
	public YjPosInfo queryYjPosInfo(String sum,String posBrandCode) throws ServiceException {
		YjPosInfo pos=new YjPosInfo();
		
		try {
			// 终端绑定时查询
			pos=terminalDao.queryYjPosInfo(sum,posBrandCode);
		} catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("查询终端终端流水号表表出错！");
		}
		
		return pos;
	}

	@Override
	public TPosInfo queryYsbYjPosInfo(String sum,String posBrandCode) throws ServiceException {
		TPosInfo pos=new TPosInfo();
		
		try {
			// 云商宝终端绑定时查询
			pos=terminalDao.queryYsbYjPosInfo(sum,posBrandCode);
		} catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("查询云商宝终端流水号表表出错！");
		}
		
		return pos;
	}


	@Override
	//开通终端
	public void clearTermInfo(String accountNo,String tid,String mid,String serialNum,String remark)
			throws ServiceException {
		try {
			List<Object> parmas = new ArrayList<Object>();
			TblTermInf termInfos=terminalDao.queryTermInfo(tid,mid);
			parmas.clear();
			if(termInfos.getStatus().equals(TerminalFlag.FLAG_ONE.getCode())){
					//冻结
					remark="操作员冻结终端成功,商户号【"+mid+"】,终端号【"+tid+"】,SN序列号【"+serialNum+"】";
					parmas.add(TerminalFlag.FLAG_THREE.getCode());
					parmas.add(termInfos.getId().getMchtCd());
					parmas.add(termInfos.getId().getTermId());
					sqlBaseDao.deleteBySql("update tbl_term_inf t set t.status=?,t.rec_upd_ts=systimestamp,t.rec_opr_id='U' where t.MCHT_CD=? and t.TERM_ID=?", parmas);					
					baseDao.addSyslog(SysLogType.TERM_FREEZE.getCode(), SysLogType.TERM_FREEZE.getName(), accountNo,remark);
					
			}else if(termInfos.getStatus().equals(TerminalFlag.FLAG_THREE.getCode())){
					//解冻
					remark="操作员解冻终端成功,商户号【"+mid+"】,终端号【"+tid+"】";
					parmas.add(TerminalFlag.FLAG_ONE.getCode());
					parmas.add(termInfos.getId().getMchtCd());
					parmas.add(termInfos.getId().getTermId());
					sqlBaseDao.deleteBySql("update tbl_term_inf t set t.status=?,t.rec_upd_ts=systimestamp,t.rec_opr_id='U' where t.MCHT_CD=? and t.TERM_ID=?", parmas);					
					baseDao.addSyslog(SysLogType.TERM_MELT.getCode(), SysLogType.TERM_MELT.getName(), accountNo,remark);
				
				}
		} catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("终端操作[冻结，解冻]出错！");
		}
		
	}

	@Override
	//添加终端序列号(未使用)
	public void saveYjPosInfo(List<YjPosInfo> posinfo, YjPosInfo pos,
			String accountNo) throws ServiceException {
		
		try {
			for (YjPosInfo yjPosInfo : posinfo) {
				YjPosInfo yp=new YjPosInfo();
				if(pos.getPosBrand()!=null){
					yp.setTekId(TerminalBrandTek.getName(pos.getPosBrand()));
				}
				yp.setSerialNum(Utils.changeCharUpperCase(yjPosInfo.getSerialNum()));
				yp.setMercCode("000000000000000");
				yp.setTermCode("00000000");
				yp.setIsBind(Terminal.BIND_TWO.getCode());//修改成未绑定
				yp.setOrgCode(pos.getOrgCode());
				yp.setPosBrand(pos.getPosBrand());
				yp.setPosName(pos.getPosName());
				yp.setPosType(pos.getPosType());
				yp.setOperators(accountNo);
				
				YjPosInfo yjPos = terminalDao.queryYjPosInfo(yjPosInfo.getSerialNum(),pos.getPosBrand());
				if(yjPos != null){
					throw new ServiceException("【"+yjPosInfo.getSerialNum()+"】序列号已存在"); 
				}
				baseDao.editSave(yp);
				
				YjPosAgent ya=new YjPosAgent();
				ya.setSerialNum(yjPosInfo.getSerialNum());
				ya.setAgentId(pos.getAgentId());
				ya.setOperators(accountNo);
				ya.setIsUsed("N");
				
				baseDao.editSave(ya);
			}
			
			
		} catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("终端流水号添加出错！");
		}
		
	}
	/**
	 * 分配序列号
	 */
	@Override
	public int SerialNumTer(List<String> terList,Operators op,String code) throws ServiceException {
		YjPosAgent yj=new YjPosAgent();
		int terCount = 0;
		try {
			Operators oprTer =  powerInfoService.loadOperatorsById(Long.parseLong(code));
			
			for (String string : terList) {
				String [] arr = string.split("_") ;
				String snCode = arr[0];
				String brandCode = arr[1];
				//查询
				String context = "操作员:"+op.getAccountNo()+"将机器序列号[" + snCode + "-" + brandCode + "]由["+op.getAccountNo()+"]分配给["+oprTer.getAccountNo()+"]";
				String  sql="update  yj_pos_agent  y set y.IS_USED=?,y.OPERATORS=?,y.DT_LASTMOD=?,y.REMARK=? "
						+"where y.SERIAL_NUM=? and y.AGENT_ID = ? and y.IS_USED = 'N' and y.POS_BRAND = ?  "
						+" and exists ( select 1 from yj_pos_info a where a.SERIAL_NUM = y.SERIAL_NUM and a.POS_BRAND = y.POS_BRAND and a.tek_id = 'Y') ";
				List<Object> paramList= new ArrayList<Object>();
				paramList.add("Y");
				paramList.add(op.getAccountNo());
				paramList.add(yj.getDtLostmod());
				paramList.add(context);
				paramList.add(snCode);
				paramList.add(op.getId());
				paramList.add(brandCode);
				int count = sqlBaseDao.deleteBySql(sql, paramList);//修改
				if ( count > 0 ) {
					// 如果地区登陆账号是 受理市场运营
					if( op.getRoleType().equals(Role.OPERATORS_LEAD.getCode()) ){
						// 查询该分配代理商的上级（除收单事业部及系统管理员）
						Map<String, String> supMap = terminalDao.selectAllSuperInfoByAgentId( oprTer);
						// 去除 系统管理员/ 收单事业部
						supMap.remove(Constant.ADMIN_ID);
						supMap.remove(Constant.SHOUDANSHIYEBU_ID);
						String userStatus = "Y";
						// 添加上级关联信息
						for (String oId : supMap.keySet()) {
							// 直属代理商状态为 未分配
							if ( oId.equals( code )) {
								userStatus = "N";
							}
							YjPosAgent yp = new YjPosAgent();
							yp.setAgentId(Long.parseLong(oId));
							yp.setIsUsed(userStatus);
							yp.setOperators(op.getAccountNo());
							yp.setSerialNum(snCode);
							yp.setRemark(context);
							yp.setPosBrand(brandCode);
							merchantDao.editSave(yp);
						}
						baseDao.addSyslog(SysLogType.TER_DIS.getCode(), SysLogType.TER_DIS.getName(),op.getAccountNo(), context);
						
					} else {
						YjPosAgent yp = new YjPosAgent();
						yp.setAgentId(Long.parseLong(code));
						yp.setIsUsed("N");
						yp.setOperators(op.getAccountNo());
						yp.setSerialNum(snCode);
						yp.setRemark(context);
						yp.setPosBrand(brandCode);
						merchantDao.editSave(yp);
						baseDao.addSyslog(SysLogType.TER_DIS.getCode(), SysLogType.TER_DIS.getName(),op.getAccountNo(), context);
					}
					terCount++;
				} else 
					logger.error(context + " 操作失败，SN号已分配给其他代理商或者已出库或SN无效,不处理");
			}
		} catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("分配终端出错！");
		}
		return terCount;
	}
	/**
	 * 云商宝分配序列号
	 */
	@Override
	public int ysbSerialNumTer(List<String> terList,Operators op,String code,String flag) throws ServiceException {
		TPosAgent yj=new TPosAgent();
		int terCount = 0;
		try {
			Operators oprTer =  powerInfoService.loadOperatorsById(Long.parseLong(code));
			for (String string : terList) {
				String [] arr = string.split("_") ;
				String snCode = arr[0];
				String brandCode = arr[1];
				List<Object> list = null;
				String context=null;
				list = terminalDao.getYsbTermapplyList("N",snCode,oprTer.getId(),brandCode,"","",op.getRoleType());
				if(list.size()>0&&!op.getRoleType().equals("14")){
					context="代理商"+op.getRoleName()+"重复分配终端"+snCode+"給"+oprTer.getRealName();
				}else{
					//查询
					context = "操作员:"+op.getAccountNo()+"将机器序列号[" + snCode + "-" + brandCode + "]由["+op.getAccountNo()+"]分配给["+oprTer.getAccountNo()+"]";
					String  sql=null;
					if(op.getRoleType().equals("14")){
						  sql="update  t_pos_agent  y set y.IS_USED=?,y.OPERATORS=?,y.DT_LASTMOD=?,y.REMARK=? ,y.flag=?,y.zs_flag='N' "
								+"where y.SERIAL_NUM=? and y.AGENT_ID = ?  and y.POS_BRAND = ?  "
								+" and exists ( select 1 from t_pos_info a where a.SERIAL_NUM = y.SERIAL_NUM and a.POS_BRAND = y.POS_BRAND and a.tek_id = 'Y') ";
					}else{
						sql="update  t_pos_agent  y set y.IS_USED=?,y.OPERATORS=?,y.DT_LASTMOD=?,y.REMARK=?,y.zs_flag='N'  "
								+"where y.SERIAL_NUM=? and y.AGENT_ID = ?  and y.POS_BRAND = ?  "
								+" and exists ( select 1 from t_pos_info a where a.SERIAL_NUM = y.SERIAL_NUM and a.POS_BRAND = y.POS_BRAND and a.tek_id = 'Y') ";	
					}
					List<Object> paramList= new ArrayList<Object>();
					paramList.add("Y");
					paramList.add(op.getAccountNo());
					paramList.add(yj.getDtLostmod());
					paramList.add(context);
					if(op.getRoleType().equals("14")){
					  paramList.add(flag);
					}
					paramList.add(snCode);
					paramList.add(op.getId());
					paramList.add(brandCode);
					int count = sqlBaseDao.deleteBySql(sql, paramList);//修改
					if ( count > 0 ) {
						String newsql="insert into t_pos_agent"
								      +"(id,serial_num,agent_id,is_used,operators,dt_create, dt_lastmod, remark,pos_brand,flag,zs_flag)"
								      +"values(seq_t_pos_agent.nextval, ?, ?, ?, ?, sysdate, sysdate, ?, ?,?,?)";
						//如果是仓库管理员分配找到直属上级
						if(op.getRoleType().equals("14")){
						  String upsql="select to_char(o.id),o.account_no from T_operators o where o.org_code ="+oprTer.getOrgCode()+"  and o.id<>"+code+" AND o.ROLE_TYPE IN (02, 03)"+
						               "START WITH id ="+code+" CONNECT BY PRIOR supri_id = id order by o.id";
						  List<Object> ob= sqlBaseDao.queryAll(upsql);
						  if (ob != null && ob.size() > 0) {
								Iterator iterator = ob.iterator();
								while (iterator.hasNext()) {
									    Object[] obj = (Object[]) iterator.next();
									    List<Object> inparamList= new ArrayList<Object>();
									    inparamList.add(snCode);
									    inparamList.add(Long.valueOf(obj[0].toString()));
									    inparamList.add("Y");
									    inparamList.add(op.getAccountNo());
									    inparamList.add(context);
									    inparamList.add(brandCode);
									    inparamList.add(flag);
									    inparamList.add("N");
									    int cnt= sqlBaseDao.deleteBySql(newsql, inparamList);//插入
									    if(cnt>0){
									     baseDao.addSyslog(SysLogType.YSB_TER_DIS.getCode(), SysLogType.YSB_TER_DIS.getName(), op.getAccountNo(), context+"单个分配");							
									     }
								  }
								}
						//所分配的人
						    List<Object> inparamList1= new ArrayList<Object>();
						    inparamList1.add(snCode);
						    inparamList1.add(Long.valueOf(oprTer.getId()));
						    inparamList1.add("N");
						    inparamList1.add(op.getAccountNo());
						    inparamList1.add(context);
						    inparamList1.add(brandCode);
						    inparamList1.add(flag);
						    inparamList1.add("Y");
						    int cnt= sqlBaseDao.deleteBySql(newsql, inparamList1);//插入
						    if(cnt>0){
							     baseDao.addSyslog(SysLogType.YSB_TER_DIS.getCode(), SysLogType.YSB_TER_DIS.getName(), op.getAccountNo(), context+"单个分配");							
							 }
						}else{
							 String newsql1="insert into t_pos_agent"
								      +"(id,serial_num,agent_id,is_used,operators,dt_create, dt_lastmod, remark,pos_brand,flag,zs_flag)"
								      +"values(seq_t_pos_agent.nextval, ?, ?, ?, ?, sysdate, sysdate, ?, ?,(select t.flag from apsmgm.t_pos_agent t where  t.serial_num =? and t.pos_brand=? and rownum = 1),'Y')";
	
							List<Object> inparamList1= new ArrayList<Object>();
						    inparamList1.add(snCode);
						    inparamList1.add(Long.valueOf(oprTer.getId()));
						    inparamList1.add("N");
						    inparamList1.add(op.getAccountNo());
						    inparamList1.add(context);
						    inparamList1.add(brandCode);
						    inparamList1.add(snCode);
						    inparamList1.add(brandCode);
						    int cnt= sqlBaseDao.deleteBySql(newsql1, inparamList1);//插入
						    if(cnt>0){
							     baseDao.addSyslog(SysLogType.YSB_TER_DIS.getCode(), SysLogType.YSB_TER_DIS.getName(), op.getAccountNo(), context+"单个分配");							
							 }
						   }
					
					}else {
						logger.error(context + " 操作失败，SN号已分配给其他代理商或者已出库或SN无效,不处理");
				 }
				}
				terCount++;
				logger.info(context+"单个分配");
			} 
		} catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("分配终端出错！");
		}
		return terCount;
	}
	
    /**
     * 批量分配终端
     */
	@Override
	public List<YjPosAgent> SerialNumTerByForExecl(List<YjPosAgent> agentList,
			Operators op, YjPosInfo pos, Operators toOperators) throws ServiceException {
		List<YjPosAgent> existList = new ArrayList<YjPosAgent>();
		try {
			List<Object> list = null;
			YjPosAgent yp = null;
			for (YjPosAgent agent : agentList) {
				list = terminalDao.getTermapplyList("N",Utils.changeCharUpperCase(agent.getSerialNum()),op.getId(),pos.getPosBrand(),"","");
				
				if (list != null && list.size() > 0) {
					
					String context = "操作员:" + op.getAccountNo() + "将机器序列号["+ agent.getSerialNum() + "-" + pos.getPosBrand() + "由[" + op.getAccountNo()+ "]通过Execl导入方式分配给[" + toOperators.getAccountNo() + "]";
					String sql = "update  yj_pos_agent  y set y.IS_USED=?,y.OPERATORS=?,y.DT_LASTMOD=sysdate,y.REMARK=? where y.SERIAL_NUM=? and y.AGENT_ID = ? and y.IS_USED = 'N' and y.POS_BRAND = ? "
							+" and exists ( select 1 from yj_pos_info a where a.SERIAL_NUM = y.SERIAL_NUM and a.POS_BRAND = y.POS_BRAND and a.tek_id = 'Y') ";
					List<Object> paramList = new ArrayList<Object>();
					paramList.add("Y");
					paramList.add(op.getAccountNo());
					paramList.add(context);
					paramList.add(Utils.changeCharUpperCase(agent.getSerialNum()));
					paramList.add(op.getId());
					paramList.add(pos.getPosBrand());
					int count = sqlBaseDao.deleteBySql(sql, paramList);// 修改
					if( count > 0 ) {

						// 如果地区登陆账号是 受理市场运营
						if( op.getRoleType().equals(Role.OPERATORS_LEAD.getCode()) ){
							// 查询该分配代理商的上级（除收单事业部及系统管理员）
							Map<String, String> supMap = terminalDao.selectAllSuperInfoByAgentId( toOperators);
							// 去除 系统管理员/ 收单事业部
							supMap.remove(Constant.ADMIN_ID);
							supMap.remove(Constant.SHOUDANSHIYEBU_ID);
							String userStatus = "Y";
							// 添加上级关联信息
							for (String oId : supMap.keySet()) {
								// 直属代理商状态为 未分配
								if ( oId.equals( String.valueOf(toOperators.getId()) )) {
									userStatus = "N";
								}
								yp = new YjPosAgent();
								yp.setAgentId(Long.parseLong(oId));
								yp.setIsUsed(userStatus);
								yp.setOperators(op.getAccountNo());
								yp.setSerialNum(Utils.changeCharUpperCase(agent.getSerialNum()));
								yp.setRemark(context);
								yp.setPosBrand(pos.getPosBrand());
								merchantDao.editSave(yp);
							}
							baseDao.addSyslog(SysLogType.TER_DIS.getCode(),SysLogType.TER_DIS.getName(), op.getAccountNo(),context);
							logger.info("成功将终端序列号【"+agent.getSerialNum()+ "-" + pos.getPosBrand() + "】分配给代理商【"+toOperators.getAccountNo()+"】");
						} else {
							yp = new YjPosAgent();
							yp.setAgentId(toOperators.getId());
							yp.setIsUsed("N");
							yp.setOperators(op.getAccountNo());
							yp.setSerialNum(Utils.changeCharUpperCase(agent.getSerialNum()));
							yp.setRemark(context);
							yp.setPosBrand(pos.getPosBrand());
							merchantDao.editSave(yp);
							baseDao.addSyslog(SysLogType.TER_DIS.getCode(),SysLogType.TER_DIS.getName(), op.getAccountNo(),context);
							logger.info("成功将终端序列号【"+agent.getSerialNum()+ "-" + pos.getPosBrand() + "】分配给代理商【"+toOperators.getAccountNo()+"】");
						}
					} else {
						existList.add(agent);
						logger.error("终端序列号【"+agent.getSerialNum()+ "-" + pos.getPosBrand() + "】已分配给其他代理商或者已出库或SN无效,不处理");
					}
					
				}else{
					existList.add(agent);
					logger.error("终端序列号【"+agent.getSerialNum()+ "-" + pos.getPosBrand() + "】已分配给其他代理商或者已出库或SN无效,不处理");
				}
				
			}
		} catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("分配终端序列号出错！");
		}
		return existList;
	}
	/**
     * 云商宝批量分配终端
     */
	@Override
	public List<TPosAgent> YsbSerialNumTerByForExecl(List<TPosAgent> agentList,
			Operators op, TPosInfo pos, Operators toOperators,String flag) throws ServiceException {
		List<TPosAgent> existList = new ArrayList<TPosAgent>();
		try {
			List<Object> list = null;
			TPosAgent yp = null;
			for (TPosAgent agent : agentList) {
				list = terminalDao.getYsbTermapplyList("N",Utils.changeCharUpperCase(agent.getSerialNum()),op.getId(),pos.getPosBrand(),"","",op.getRoleType());
				
				if (list != null && list.size() > 0) {
					String context = "操作员:" + op.getAccountNo() + "将机器序列号["+ agent.getSerialNum() + "-" + pos.getPosBrand() + "由[" + op.getAccountNo()+ "]通过Execl导入方式分配给[" + toOperators.getAccountNo() + "]";
					String sql=null;				
					if(op.getRoleType().equals("14")){
						sql = "update  t_pos_agent  y set y.IS_USED=?,y.OPERATORS=?,y.DT_LASTMOD=sysdate,y.REMARK=? , y.flag=?,y.zs_flag='N'  where y.SERIAL_NUM=? and y.AGENT_ID = ?  and y.POS_BRAND = ? "
								+" and exists ( select 1 from t_pos_info a where a.SERIAL_NUM = y.SERIAL_NUM and a.POS_BRAND = y.POS_BRAND and a.tek_id = 'Y') ";
                      }else{
                    	sql = "update  t_pos_agent  y set y.IS_USED=?,y.OPERATORS=?,y.DT_LASTMOD=sysdate,y.REMARK=?,y.zs_flag='N'   where y.SERIAL_NUM=? and y.AGENT_ID = ?  and y.POS_BRAND = ? "
  								+" and exists ( select 1 from t_pos_info a where a.SERIAL_NUM = y.SERIAL_NUM and a.POS_BRAND = y.POS_BRAND and a.tek_id = 'Y') ";
                       }
					List<Object> paramList = new ArrayList<Object>();
					paramList.add("Y");
					paramList.add(op.getAccountNo());
					paramList.add(context);
					if(op.getRoleType().equals("14")){
					paramList.add(flag);
					}
					paramList.add(Utils.changeCharUpperCase(agent.getSerialNum()));
					paramList.add(op.getId());
					paramList.add(pos.getPosBrand());
					int count = sqlBaseDao.deleteBySql(sql, paramList);// 修改
					if( count > 0 ) {
						String newsql="insert into t_pos_agent"
							      +"(id,serial_num,agent_id,is_used,operators,dt_create, dt_lastmod, remark,pos_brand,flag,zs_flag )"
							      +"values(seq_t_pos_agent.nextval, ?, ?, ?, ?, sysdate, sysdate, ?, ?,?,?)";
						//如果是仓库管理员分配找到直属上级
						if(op.getRoleType().equals("14")){
						  String upsql="select to_char(o.id),o.account_no from T_operators o where o.org_code ="+toOperators.getOrgCode()+"  and o.id<>"+toOperators.getId()+" AND o.ROLE_TYPE IN (02, 03)"+
						               "START WITH id ="+toOperators.getId()+" CONNECT BY PRIOR supri_id = id order by o.id";
						  List<Object> ob= sqlBaseDao.queryAll(upsql);
						  if (ob != null && ob.size() > 0) {
								Iterator iterator = ob.iterator();
								while (iterator.hasNext()) {
									    Object[] obj = (Object[]) iterator.next();
									    List<Object> inparamList= new ArrayList<Object>();
									    inparamList.add(Utils.changeCharUpperCase(agent.getSerialNum()));
									    inparamList.add(Long.valueOf(obj[0].toString()));
									    inparamList.add("Y");
									    inparamList.add(op.getAccountNo());
									    inparamList.add(context);
									    inparamList.add(pos.getPosBrand());
									    inparamList.add(flag);
									    inparamList.add("N");
									    int cnt= sqlBaseDao.deleteBySql(newsql, inparamList);//插入
									    if(cnt>0){
											baseDao.addSyslog(SysLogType.YSB_TER_DIS.getCode(),SysLogType.YSB_TER_DIS.getName(),  op.getAccountNo(),context+"批量分配");
										 }
										}
								}
						    List<Object> inparamList= new ArrayList<Object>();
						    inparamList.add(Utils.changeCharUpperCase(agent.getSerialNum()));
						    inparamList.add(Long.valueOf(toOperators.getId()));
						    inparamList.add("N");
						    inparamList.add(op.getAccountNo());
						    inparamList.add(context);
						    inparamList.add(pos.getPosBrand());
						    inparamList.add(flag);
						    inparamList.add("Y");
						    int cnt= sqlBaseDao.deleteBySql(newsql, inparamList);//插入
						    if(cnt>0){
								baseDao.addSyslog(SysLogType.YSB_TER_DIS.getCode(),SysLogType.YSB_TER_DIS.getName(),  op.getAccountNo(),context+"批量分配");
							 }
						   }else{
						   String newsql1="insert into t_pos_agent"
								      +"(id,serial_num,agent_id,is_used,operators,dt_create, dt_lastmod, remark,pos_brand,flag,zs_flag)"
								      +"values(seq_t_pos_agent.nextval, ?, ?, ?, ?, sysdate, sysdate, ?, ?,(select t.flag from apsmgm.t_pos_agent t where  t.serial_num =? and t.pos_brand=? and rownum = 1),'Y')";

						    List<Object> inparamList= new ArrayList<Object>();
						    inparamList.add(Utils.changeCharUpperCase(agent.getSerialNum()));
						    inparamList.add(Long.valueOf(toOperators.getId()));
						    inparamList.add("N");
						    inparamList.add(op.getAccountNo());
						    inparamList.add(context);
						    inparamList.add(pos.getPosBrand());
						    inparamList.add(Utils.changeCharUpperCase(agent.getSerialNum()));
						    inparamList.add(pos.getPosBrand());
						    int cnt= sqlBaseDao.deleteBySql(newsql1, inparamList);//插入
						    if(cnt>0){
								baseDao.addSyslog(SysLogType.YSB_TER_DIS.getCode(),SysLogType.YSB_TER_DIS.getName(),  op.getAccountNo(),context+"批量分配");
							 }	
						  }
						logger.info("成功将终端序列号【"+agent.getSerialNum()+ "-" + pos.getPosBrand() + "】+批量分配给代理商【"+toOperators.getAccountNo()+"】");
					} else {
						existList.add(agent);
						logger.error("终端序列号【"+agent.getSerialNum()+ "-" + pos.getPosBrand() + "】已分配给其他代理商或者已出库或SN无效,不处理");
					}
					
				}else{
					existList.add(agent);
					logger.error("终端序列号【"+agent.getSerialNum()+ "-" + pos.getPosBrand() + "】已分配给其他代理商或者已出库或SN无效,不处理");
				}
				
			}
		} catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("分配终端序列号出错！");
		}
		return existList;
	}
	
	 /**
     * 云商宝终端序列号批量分配重构方法，添加判断序列号t_pos_info表是否有记录
     */
	@Override
	public Map<String, List<TPosAgent>> getYsbSeriaNumListForExeclMap(
			List<TPosAgent> agentList, Operators op, TPosInfo pos, Operators toOperators,String flag)
			throws ServiceException {
		Map<String, List<TPosAgent>> map = new HashMap<String, List<TPosAgent>>();
		List<TPosAgent> notExistposInfoList = new ArrayList<TPosAgent>();
		List<TPosAgent> posAgentList = new ArrayList<TPosAgent>();
		List<Object> posInfListQueryList = new ArrayList<Object>();
		//notExistposInfoList = getNotExistPosInfoList(agentList,pos);
		long totalNum=0;
		for(TPosAgent agent :agentList){
			// 通过 sn 和 厂商 查询 是否有记录
			totalNum = terminalDao.getTPosInfo(Utils.changeCharUpperCase(agent.getSerialNum()),pos.getPosBrand(),"","");
			if(totalNum<=0){
				notExistposInfoList.add(agent);
				logger.info("终端序列号["+agent.getSerialNum()+"]不存在，请确认");
			}
		}
		if(notExistposInfoList!=null && notExistposInfoList.size()>0){
			map.put("posInfo", notExistposInfoList);//不存在序列号的对象存放在map
			return map;
		}
		else{
			posAgentList = YsbSerialNumTerByForExecl(agentList, op, pos, toOperators,flag);
			map.put("posAgent", posAgentList);//已经分配过的序列号的对象存放在map
		}
		return map;
	}
	
    /**
     * 终端序列号批量分配重构方法，添加判断序列号yj_pos_info表是否有记录
     */
	@Override
	public Map<String, List<YjPosAgent>> getSeriaNumListForExeclMap(
			List<YjPosAgent> agentList, Operators op, YjPosInfo pos, Operators toOperators)
			throws ServiceException {
		Map<String, List<YjPosAgent>> map = new HashMap<String, List<YjPosAgent>>();
		List<YjPosAgent> notExistposInfoList = new ArrayList<YjPosAgent>();
		List<YjPosAgent> posAgentList = new ArrayList<YjPosAgent>();
		List<Object> posInfListQueryList = new ArrayList<Object>();
		//notExistposInfoList = getNotExistPosInfoList(agentList,pos);
		long totalNum=0;
		for(YjPosAgent agent :agentList){
			// 通过 sn 和 厂商 查询 是否有记录
			totalNum = terminalDao.getPosInfo(Utils.changeCharUpperCase(agent.getSerialNum()),pos.getPosBrand(),"","");
			if(totalNum<=0){
				notExistposInfoList.add(agent);
				logger.info("终端序列号["+agent.getSerialNum()+"]不存在，请确认");
			}
		}
		if(notExistposInfoList!=null && notExistposInfoList.size()>0){
			map.put("posInfo", notExistposInfoList);//不存在序列号的对象存放在map
			return map;
		}
		else{
			posAgentList = SerialNumTerByForExecl(agentList, op, pos, toOperators);
			map.put("posAgent", posAgentList);//已经分配过的序列号的对象存放在map
		}
		return map;
	}

	private List<YjPosAgent> getNotExistPosInfoList(List<YjPosAgent> list,YjPosInfo pos){
		long totalNum=0;
	    List<YjPosAgent> posInfoList = new ArrayList<YjPosAgent>();
		for(YjPosAgent agent :list){
			totalNum = terminalDao.getPosInfo(Utils.changeCharUpperCase(agent.getSerialNum()), pos.getPosBrand(), pos.getPosType(), pos.getPosName());
			if(totalNum<=0){
				posInfoList.add(agent);
				logger.info("终端序列号["+agent.getSerialNum()+"]不存在，请确认");
			}
		}
		return posInfoList;
	}
	@Override
	public List<YjPosInfo> batchSaveSeriaNum(List<YjPosInfo> posinfo,
			YjPosInfo pos, Operators operators) throws ServiceException {
		YjPosInfo bean=null;
		List<YjPosInfo> importedList=new ArrayList<YjPosInfo>();
		int total=0;
		try {
			pos.setAgentId(operators.getId());
			for (YjPosInfo yjPosInfo : posinfo) {
				bean=new YjPosInfo();
			/*	if(pos.getPosBrand()!=null){
					bean.setTekId(TerminalBrandTek.getName(pos.getPosBrand()));
				}*/
				bean.setSerialNum(Utils.changeCharUpperCase(yjPosInfo.getSerialNum()));
				bean.setMercCode(Constant.MERC_CODE_DEFAULT);
				bean.setTermCode(Constant.TERM_CODE_DEFAULT);
				bean.setIsBind(Terminal.BIND_TWO.getCode());//修改成未绑定
				bean.setOrgCode(pos.getOrgCode());
				bean.setPosBrand(pos.getPosBrand());
				bean.setPosName(pos.getPosName());
				bean.setPosType(pos.getPosType());
				bean.setOperators(operators.getAccountNo());
				bean.setUpdateFlag("N");
				bean.setAssefFlag( pos.getAssefFlag() );
				bean.setRemark("由操作员【"+operators.getAccountNo() +"】导入序列号【"+bean.getSerialNum()+ "-" + pos.getPosBrand() + "】");

				bean.setTekId(Terminal.BIND_ONE.getCode());// 现存 有效状态，默认Y有效
				// 同一个品牌,同一个sn只能有一个
				YjPosInfo tempObj = terminalDao.queryYjPosInfo(Utils.changeCharUpperCase(yjPosInfo.getSerialNum()),pos.getPosBrand());
				if(tempObj != null){//已经存在记录
					YjPosInfo temp=new YjPosInfo();
					temp.setSerialNum(tempObj.getSerialNum());

					String brandCode = tempObj.getPosBrand();
					String typeCode = tempObj.getPosType();
					String nameCode = tempObj.getPosName();
					
					temp.setPosBrand(ConfigMerinfoUtil.getPosBRAND(brandCode));
					temp.setPosName(ConfigMerinfoUtil.getPosMODEL(nameCode , brandCode));
					temp.setPosType(ConfigMerinfoUtil.getTerminalType(typeCode));
					
					temp.setRemark(tempObj.getRemark());
					importedList.add(temp);
					logger.info("##########操作员【"+operators.getAccountNo()+"】导入序列号【"+bean.getSerialNum() + "-" + brandCode + "】给代理商【"+operators.getAccountNo()+"】时重复，不处理##########");
				}else{//不存在记录
					 baseDao.editSave(bean);
					 YjPosAgent posAgent = new YjPosAgent();
					 posAgent.setSerialNum(Utils.changeCharUpperCase(yjPosInfo.getSerialNum()));
					 posAgent.setAgentId(pos.getAgentId());
					 posAgent.setOperators(operators.getAccountNo());
					 posAgent.setIsUsed("N");
					 posAgent.setRemark("由操作员【"+operators.getAccountNo()+"】导入序列号【"+bean.getSerialNum()+ "-" + pos.getPosBrand() + "】给代理商【"+operators.getAccountNo()+"】");

					 posAgent.setPosBrand(pos.getPosBrand());
					 baseDao.editSave(posAgent);
					 total++;
					 logger.info("##########操作员【"+operators.getAccountNo()+"】成功导入序列号【"+bean.getSerialNum() + "-" + pos.getPosBrand() + "】给代理商【"+operators.getAccountNo()+"】##########");
						
				}
				
		       }
			 baseDao.addSyslog(SysLogType.TER_DIS.getCode(),SysLogType.TER_DIS.getName(),operators.getAccountNo(),"操作员【"+operators.getAccountNo()+"】成功导入【"+total+"】个终端号给代理商【"+operators.getAccountNo()+"】");
				
		} catch (DaoException e) {
			logger.error(e.getMessage(),e);
			throw new ServiceException("终端序号批量导入失败");
		}
		return importedList;
	}
	
	@Override
	public List<TPosInfo> batchSaveYsbSeriaNum(List<TPosInfo> posinfo,
			TPosInfo pos, Operators operators) throws ServiceException {
		TPosInfo bean=null;
		List<TPosInfo> importedList=new ArrayList<TPosInfo>();
		int total=0;
		try {
			pos.setAgentId(operators.getId());
			for (TPosInfo tPosInfo : posinfo) {
				bean=new TPosInfo();
			/*	if(pos.getPosBrand()!=null){
					bean.setTekId(TerminalBrandTek.getName(pos.getPosBrand()));
				}*/
				bean.setSerialNum(Utils.changeCharUpperCase(tPosInfo.getSerialNum()));
				bean.setMercCode(Constant.MERC_CODE_DEFAULT);
				bean.setTermCode(Constant.TERM_CODE_DEFAULT);
				bean.setIsBind(Terminal.BIND_TWO.getCode());//修改成未绑定
				bean.setOrgCode(pos.getOrgCode());
				bean.setPosBrand(pos.getPosBrand());
				bean.setPosName(pos.getPosName());
				bean.setPosType(pos.getPosType());
				bean.setOperators(operators.getAccountNo());
				bean.setUpdateFlag("N");
				bean.setAssefFlag( pos.getAssefFlag() );
				bean.setRemark("由操作员【"+operators.getAccountNo() +"】导入云商宝序列号【"+bean.getSerialNum()+ "-" + pos.getPosBrand() + "】");

				bean.setTekId(Terminal.BIND_ONE.getCode());// 现存 有效状态，默认Y有效
				// 同一个品牌,同一个sn只能有一个
				TPosInfo tempObj = terminalDao.queryYsbYjPosInfo(Utils.changeCharUpperCase(tPosInfo.getSerialNum()),pos.getPosBrand());
				if(tempObj != null){//已经存在记录
					TPosInfo temp=new TPosInfo();
					temp.setSerialNum(tempObj.getSerialNum());

					String brandCode = tempObj.getPosBrand();
					String typeCode = tempObj.getPosType();
					String nameCode = tempObj.getPosName();
					
					temp.setPosBrand(ConfigMerinfoUtil.getPosBRAND(brandCode));
					temp.setPosName(ConfigMerinfoUtil.getPosMODEL(nameCode , brandCode));
					temp.setPosType(ConfigMerinfoUtil.getTerminalType(typeCode));
					
					temp.setRemark(tempObj.getRemark());
					importedList.add(temp);
					logger.info("##########操作员【"+operators.getAccountNo()+"】导入云商宝序列号【"+bean.getSerialNum() + "-" + brandCode + "】给代理商【"+operators.getAccountNo()+"】时重复，不处理##########");
				}else{//不存在记录
					baseDao.editSave(bean);
					List<Object> params=new ArrayList<Object>();
					params.add(Utils.changeCharUpperCase(tPosInfo.getSerialNum()));
					params.add(pos.getAgentId());	
					params.add("N");	
					params.add(operators.getAccountNo());
					params.add("由操作员【"+operators.getAccountNo()+"】导入云商宝序列号【"+bean.getSerialNum()+ "-" + pos.getPosBrand() + "】给代理商【"+operators.getAccountNo()+"】");
					params.add(pos.getPosBrand());
					params.add("Y");
					sqlBaseDao.deleteBySql("insert into t_pos_agent  (id,serial_num,agent_id,is_used,operators,dt_create, dt_lastmod, remark,pos_brand,ZS_FLAG) values(seq_t_pos_agent.nextval,?,?,?,?,systimestamp,systimestamp,?,?,?)", params);
					
					total++;
					logger.info("##########操作员【"+operators.getAccountNo()+"】成功导入云商宝序列号【"+bean.getSerialNum() + "-" + pos.getPosBrand() + "】给代理商【"+operators.getAccountNo()+"】##########");
						
				}
				
		       }
			 baseDao.addSyslog(SysLogType.YSB_TER_DIS.getCode(),SysLogType.YSB_TER_DIS.getName(),operators.getAccountNo(),"操作员【"+operators.getAccountNo()+"】成功导入【"+total+"】个终端号给代理商【"+operators.getAccountNo()+"】");
				
		} catch (DaoException e) {
			logger.error(e.getMessage(),e);
			throw new ServiceException("云商宝终端序号批量导入失败");
		}
		return importedList;
	}

	@Override
	public List<Long> getOpertorsIdsTreeById(Long id) throws ServiceException {
		// TODO Auto-generated method stub
		List list = null;
		List idList = new ArrayList<Long>(); 
		try{
			list = terminalDao.getOpertorsIdsTreeById(id);
			if(list!=null && list.size()>0){
				Iterator iterator=list.iterator();
				BigDecimal value = null;
				for(int i=0;i<list.size();i++){
					value =(BigDecimal)list.get(i);
					idList.add(value.longValue());
				}
//				while (iterator.hasNext()) {
//					Object[] obj= (Object[])iterator.next();
//					value = (BigDecimal)obj[0];
//					idList.add(value.longValue());
//				}
			}
		}
		catch(DaoException e){
			logger.debug(e.getMessage());
			throw new ServiceException("查询操作员ID树信息出错！");
		}
		return idList;
	}
    
	@Override
	public int terminalAllotRecallBySN(List<String> serialList,Operators operators,Operators agent )
			throws ServiceException {
		int total=0;
		
		try{	
			String params=Constance.list2SqlStr(serialList);
		   if(operators.getRoleType().trim().equals("00")||operators.getRoleType().trim().equals("01")){//管理员和系统管理员
				String sql1="DELETE FROM yj_pos_info y WHERE y.serial_num IN("+params+")";	
			    String sql2="DELETE FROM yj_pos_agent y WHERE y.serial_num IN("+params+")";
				total=sqlBaseDao.deleteBySql(sql1, null);
				logger.info("######yj_pos_info["+sql1+"],删除["+total+"]个######");
				
				int temp=sqlBaseDao.deleteBySql(sql2, null);
				logger.info("######yj_pos_agent["+sql2+"],删除["+temp+"]个######");
				logger.info("########管理员【"+operators.getAccountNo()+"】撤回【"+agent.getAccountNo()+"】【"+total+"】个终端序列号【"+params+"】#######");
		   }
		   else{//代理商
				String sqlDel=" DELETE FROM YJ_POS_AGENT M "+
						   " WHERE M.AGENT_ID IN (SELECT DISTINCT T.ID "+
						   " FROM T_OPERATORS T START WITH ID = "+agent.getId()+" AND T.ROLE_TYPE <> '15' "+
						   " CONNECT BY PRIOR T.ID = T.Supri_Id) AND M.SERIAL_NUM IN ("+params+")";
				String sqlUpdate=" UPDATE yj_pos_agent y SET y.is_used='N',y.remark='自代理商【"+agent.getAccountNo()+"】名下撤回',y.dt_lastmod=SYSDATE "+
								 " WHERE y.agent_id="+operators.getId()+" AND y.is_used='Y' AND y.serial_num IN("+params+") "+
								 " AND exists(SELECT 1 FROM yj_pos_agent p WHERE p.serial_num=y.serial_num AND p.agent_id="+agent.getId()+") ";
				total=sqlBaseDao.deleteBySql(sqlUpdate, null);
				logger.info("######yj_pos_agent["+sqlUpdate+"],更新["+total+"]个######");
				
				int temp=sqlBaseDao.deleteBySql(sqlDel, null);
				logger.info("######yj_pos_agent["+sqlDel+"],删除["+temp+"]个######");
				logger.info("########操作员【"+operators.getAccountNo()+"】撤回【"+agent.getAccountNo()+"】【"+total+"】个终端序列号【"+params+"】#######");
		  
		   }
						
	       baseDao.addSyslog(SysLogType.TERM_ALLOT_RECALL.getCode(),SysLogType.TERM_ALLOT_RECALL.getName(),operators.getAccountNo(),"操作员【"+operators.getAccountNo()+"】撤回【"+agent.getAccountNo()+"】【"+total+"】个终端序列号【"+params+"】");
			
         }
		catch(DaoException e){
			logger.error(e.getMessage());
			throw new ServiceException("撤回代理的终端序列号出错！");
		}
		return total;
	}
	/**
	 * 
	 * @param list
	 * @param op
	 * @return
	 */
	private List<Long> getOperatorsChildIdList(List<Long> list,Operators op){
		List childList = new ArrayList<Long>();
		if(list!=null && list.size()>0){
			for(Long id:list){
				if(op.getId()!=id){
					childList.add(id);
				}
			}
		}
		return childList;
	}

	@Override
	public List getPosInfosForBatchRecall(String seriaNum,String orgCode,Long agentId,
			String posBrand, String posType, String posName,Operators op)
			throws ServiceException {
		List list = new ArrayList();
		try{
			if(op.getRoleType().trim().equals("00")||op.getRoleType().trim().equals("01")){
				list = terminalDao.getPosInfosForBatchRecall(seriaNum,orgCode,agentId,posBrand, posType, posName,"N");	
			}else{
				list = terminalDao.getPosInfosForBatchRecall(seriaNum,orgCode,agentId,posBrand, posType, posName,"Y");	

			}
		}
		catch(Exception e){
			logger.debug(e.getMessage());
			throw new ServiceException("批量撤回查询删除POS代理信息出错！");
		}
		return list;
	}

	@Override
	public List<TermBean> queryTermChangeByMid(String merchantNo)
			throws ServiceException {
		// TODO Auto-generated method stub
		List<TermBean> obj=null;
		try {
			obj= terminalDao.queryTerChangeByMid(merchantNo);
		} catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("查询终端出错！");
		}
		return obj;
	
	}

	
	
	
	/**
	 * 通过商户号修改所有的终端状态
	 * @param mid
	 * @param flag
	 * @param accountNo
	 * @return
	 * @throws ServiceException
	 */
	public int updateEstidinfoFlag(String mid,int flag,String accountNo) throws ServiceException{
		
		int i = 0;
		try {
			String logCode = "";
			String logName = "";
			String updateFlag = "";
			if(MerchantStatus.S_1.getCode()==flag){
				logCode = SysLogType.TERM_MELT.getCode();
				logName = SysLogType.TERM_MELT.getName();
				updateFlag = TerminalFlag.FLAG_ONE.getCode();
			}else if(MerchantStatus.S_13.getCode()==flag){
				logCode = SysLogType.TERM_FREEZE.getCode();
				logName = SysLogType.TERM_FREEZE.getName();
				updateFlag = TerminalFlag.FLAG_THREE.getCode();				
			}else{
				return i;
			}
			String sql = "update  ESTIDINFO set flag  = '"+updateFlag+"' where mid = '"+mid+"' ";
			i = sqlBaseDao.executeBySql(sql);
			merchantDao.addSyslog(logCode,logName,accountNo, "操作员【"+accountNo+"】对商户【"+mid+"】的终端操作了【"+logName+"】");
		
		} catch (DaoException e) {
			logger.error(e.getMessage(),e);
			throw new ServiceException(e.getMessage());
		}
		
		
		return i;
	}
	
	
	/**
	 * 终端序列号解除绑定
	 * @param yjPos
	 * @param accountNo
	 * @throws ServiceException
	 */
	public void unbindingTerminalSn(YjPosInfo yjPos,String accountNo,String mid,long agentId) throws ServiceException {
		
		try{
			Object object=baseDao.createSQLQueryUniqueResult("select ori_sn from yj_sn_info s where s.merc_code="+mid+" and s.term_code="+yjPos.getTermCode());
			List<Object> params=new ArrayList<Object>();
			//params.add("代理商【"+accountNo+"】进行解绑操作");			
			params.add(String.valueOf(object));
			params.add(yjPos.getSerialNum());
			params.add(yjPos.getTermCode());
			params.add(mid);
			sqlBaseDao.deleteBySql(" UPDATE tbl_term_inf t SET t.device_cd=?,t.rec_upd_ts=systimestamp,t.REC_OPR_ID='U',t.status='02' WHERE t.device_cd=? and t.TERM_ID=? and t.MCHT_CD=?", params);
			params.clear();
			params.add(Constant.MERC_CODE_DEFAULT);
			params.add(Constant.TERM_CODE_DEFAULT);
			params.add(Terminal.BIND_TWO.getCode());
			
			params.add(yjPos.getTermCode());
			params.add(yjPos.getSerialNum());
			sqlBaseDao.deleteBySql(" UPDATE yj_pos_info y SET y.merc_code=?,y.term_code=?,y.is_bind=? WHERE y.term_code=?  AND y.serial_num=? ", params);
			params.clear();
			params.add("代理商【"+accountNo+"】对终端【"+yjPos.getTermCode()+"】进行解绑操作");
			params.add(yjPos.getSerialNum());
			params.add(agentId);
			sqlBaseDao.deleteBySql("UPDATE yj_pos_agent y SET y.is_used='N',y.remark=? ,y.dt_lastmod=systimestamp WHERE y.serial_num=? AND y.agent_id=? ", params);
			logger.info("###########代理商【"+accountNo+"】对终端【"+yjPos.getTermCode()+"】进行解绑操作############");
			/*TermInfo terminfo=terminalDao.querTermInfo(yjPos.getTermCode());
			
			//terminfo.setInstallStatus(Terminal.BIND_TWO.getCode());
			terminfo.setSerialNum(null);
			baseDao.editUpdate(terminfo);
			
			YjPosInfo yjPosInfo=terminalDao.queryYjPosInfo(yjPos.getSerialNum());
			yjPosInfo.setMercCode(Constant.MERC_CODE_DEFAULT);
			yjPosInfo.setTermCode(Constant.TERM_CODE_DEFAULT);
			yjPosInfo.setIsBind(Terminal.BIND_TWO.getCode());
			baseDao.editUpdate(yjPosInfo);
			
			//修改出库状态
			updateAgentIsUsed(yjPos.getSerialNum(), agentId, "N");*/
			
			baseDao.addSyslog(SysLogType.TERM_UNBUND.getCode(), SysLogType.TERM_UNBUND.getName(), accountNo, "操作员"+accountNo+"解绑终端序列号成功,商户号【"+mid+"】,终端号【"+yjPos.getTermCode()+"】,序列号【"+yjPos.getSerialNum()+"】");
		
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			throw new ServiceException("解绑终端序列号出错！SerialNum:"+yjPos.getSerialNum());
		}
		
	}
	
	/**
	 * 终端序列号重新绑定
	 * @param mid
	 * @param tid
	 * @param serialNum
	 * @param accountNo
	 * @throws ServiceException
	 */
	public void reBindingTerminalSn(String mid,String tid,String serialNum,String posBrandCode,String accountNo,long agentId) throws ServiceException {
		
		try {
			//TermInfo terminfo=terminalDao.querTermInfo(tid);
			TblTermInf terminfos=terminalDao.queryTermInfo(tid, mid);
			terminfos.setDeviceCd(serialNum);
			//terminfo.setInstallStatus(Terminal.BIND_ONE.getCode());
			//terminfo.setSerialNum(serialNum);
			baseDao.editUpdate(terminfos);
			
			YjPosInfo yjPosInfo=terminalDao.queryYjPosInfo(serialNum, posBrandCode);
			yjPosInfo.setMercCode(mid);
			yjPosInfo.setTermCode(tid);
			yjPosInfo.setIsBind(Terminal.BIND_ONE.getCode());
			baseDao.editUpdate(yjPosInfo);
			
			//修改出库状态
			//updateAgentIsUsed(serialNum, agentId, "Y");
			List<Object> params=new ArrayList<Object>();
			params.add("代理商【"+accountNo+"】重绑终端【"+tid+"】的序列号为【"+serialNum+"】");
			params.add(serialNum);
			params.add(agentId);
			sqlBaseDao.deleteBySql("UPDATE yj_pos_agent y SET y.is_used='Y',y.remark=? ,y.dt_lastmod=SYSDATE WHERE y.serial_num=? AND y.agent_id=? ", params);
			
			baseDao.addSyslog(SysLogType.TERM_SUM.getCode(), SysLogType.TERM_SUM.getName(), accountNo, "操作员"+accountNo+"重新绑定终端序列号成功，终端号【"+tid+"】,序列号【"+serialNum+"】");
			logger.info("###########代理商【"+accountNo+"】重绑终端【"+tid+"】的序列号为【"+serialNum+"】############");
			
			
		} catch (Exception e) {
			logger.debug(e.getMessage());
			throw new ServiceException("重新绑定终端序列号出错！SerialNum:"+serialNum);
		}
		
	}
	
	
	/**
	 * 更新出库状态
	 * @param serialNum
	 * @param agentId
	 * @param flag
	 * @return
	 * @throws ServiceException
	 */
	public int updateAgentIsUsed(String serialNum,long agentId,String flag)throws ServiceException{
		
		//修改出库状态
		int i = 0;
		String sql="update yj_pos_agent set IS_USED = '"+flag+"' where SERIAL_NUM = '"+serialNum+"' and agent_id = "+agentId+"  "; 
		try {
			i = sqlBaseDao.deleteBySql(sql, null);
		} catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("更新终端出库状态失败serialNum:"+serialNum+",agentId:"+agentId);
		}
		return i;
		
	}
	@Override
	public void insertTermInfoTmpByTid(String tid,String accounNo,String mid) throws ServiceException {
		// TODO Auto-generated method stub
		TermInfo terminfo=new TermInfo();
		TermInfoTmp termInfoTmp=new TermInfoTmp();
		
		try {
			terminfo=terminalDao.querTermInfo(tid);
			termInfoTmp.setTermId(terminfo.getTermId());
			termInfoTmp.setTermAddr(terminfo.getTermAddr());
			termInfoTmp.setTerminalName(terminfo.getTerminalName());
			termInfoTmp.setSerialNum(terminfo.getSerialNum());
			termInfoTmp.setInstallStatus(terminfo.getInstallStatus());
			termInfoTmp.setOperators(accounNo);
			termInfoTmp.setMid(mid);
			termInfoTmp.setDt_create(new Date());
			termInfoTmp.setDt_lastmod(new Date());
			baseDao.editSave(termInfoTmp);
			logger.info("########商户申请注销终端,操作员【"+accounNo+"】申请注销终端【"+tid+"】,商户号"+mid);
			terminalDao.addSyslog(SysLogType.MERINFO_CHANGE_ZONGDUAN.getCode(), SysLogType.MERINFO_CHANGE_ZONGDUAN.getName(), accounNo, "商户【"+accounNo+"】申请注销终端！");
			//terminfo.setEstidinfo(terminalDao.queryEstidinfo(tid));
			//terminfo.setTermFlag(TerminalFlag.valueOfCode(terminfo.getEstidinfo().getFlag()).getName());
		} catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("保存终端临时信息表出错！");
		}
	}

	@Override
	public List<TermInfoTmp> queryTermInfoTmpByMid(String mid)
			throws ServiceException {
		// TODO Auto-generated method stub
		List<TermInfoTmp> termInfoList=null;
		try{
			termInfoList=terminalDao.queryTermInfoTmpByMid(mid);
		}catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("查询终端临时信息表出错！");
		}
		return termInfoList;
	}

	@Override
	public void delTermInfoTmpByMid(String accounNo, String mid)
			throws ServiceException {
		// TODO Auto-generated metho
		List<TermInfoTmp> termList=null;
		try{
			termList=terminalDao.queryTermInfoTmpByMid(mid);
			for(int i=0;i<termList.size();i++){
				if(!Constance.Null2EmptyTrim(termList.get(i).getSerialNum()).equals("")){
					baseDao.delete(termList.get(i));
				}
			}
			
		}catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("更新终端临时信息表出错！");
		}
		
	}

	@Override
	public List<TermInfoTmp> queryTermNULLTmpByMid(String mid)
			throws ServiceException {
		// TODO Auto-generated method stub
		List<TermInfoTmp> termInfoList=null;
		try{
			termInfoList=terminalDao.queryTermTmpNULLByMid(mid);
		}catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("查询终端临时信息表出错！");
		}
		return termInfoList;
	}
	
	
	@Override
	//终端添加
	public  synchronized void saveTidRecord(TidRecord tid)
			throws ServiceException {
		
		try {
		
				terminalDao.editSave(tid);
				
				/**添加终端记录日志**/
				//baseDao.addSyslog(SysLogType.TERM_ADD.getCode(), SysLogType.TERM_ADD.getName(), account, "操作员"+account+"添加终端成功，终端号【"+maxNo+"】");
	
		} catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("添加终端记录出错！");
		}
		
	}

	/**
	 * 查询型号
	 */
	@Override
	public List<Map<String, Object>> selModelItemByType(
			TblDictionaryLayerItem item) throws ServiceException {
		List<Map<String, Object>> queryResult = new ArrayList<Map<String,Object>>();
		try{
			item.getId().setDicType("TMNL_MODEL_NO");
			List<TblDictionaryLayerItem> termInfoList=terminalDao.queryModelItemByType(item);
			for (TblDictionaryLayerItem tblDictionaryLayerItem : termInfoList) {
				Map<String,Object> map = new TreeMap<String, Object>();
			
				String dicCode = tblDictionaryLayerItem.getId().getDicCode();
				String dicName = tblDictionaryLayerItem.getName();
				 
				
				map.put("CODE", dicCode);
				map.put("NAME", dicName);
				queryResult.add(map);
			}
			
		}catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("查询型号信息表出错！");
		}
		return queryResult;
	}

	/**
	 * 查询品牌
	 */
	@Override
	public Map<String,String> selBrandItemByType(TblDictionaryItem item)
			throws ServiceException {
		Map<String,String> map=new TreeMap<String, String>();
		String symbol = "like";
		try{
			item.getId().setDicType("TMNL_BRAND%");
			List<TblDictionaryItem> termInfoList=terminalDao.queryDictionaryItemByType(item ,  symbol);
			
			for (TblDictionaryItem tblDictionaryItem : termInfoList) {
				String dicCode = tblDictionaryItem.getId().getDicCode();
				String dicName = tblDictionaryItem.getDicName();
				String [] arr = dicName.split("_");
				
				map.put(dicCode, (arr.length > 0 ? arr[1] : dicName));
			}
		}catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("查询品牌信息表出错！");
		}
		return map;
	}

	/**
	 * 查询类型
	 */
	@Override
	public Map<String,String> selTypeItemByType(TblDictionaryItem item)
			throws ServiceException {
		Map<String,String> map=new TreeMap<String, String>();
		String symbol = "=";
		try{
			item.getId().setDicType("Terminal_Type");
			List<TblDictionaryItem> termInfoList=terminalDao.queryDictionaryItemByType(item , symbol);

			for (TblDictionaryItem tblDictionaryItem : termInfoList) {
				String dicCode = tblDictionaryItem.getId().getDicCode();
				String dicName = tblDictionaryItem.getDicName();
				String [] arr = dicName.split("_");
				map.put(dicCode,  (arr.length > 0 ? arr[1] : dicName));
			}
		}catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("查询类型信息表出错！");
		}
		return map;
	}

	@Override
	public void setSerialNumber(String termID,String merchtNo,YjPosInfo yjPos,String orgCode)
			throws ServiceException {
		try {
			terminalDao.setSerialNumber(termID,merchtNo,yjPos,orgCode);
		} catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("分配SN序列号出错!");
		}
	}

	@Override
	public void updateSerialNumberStatus(String serialNum,String posBrandCode,long agentid,String accountNo,String tid)
			throws ServiceException {
		try {
			terminalDao.updateSerialNumberStatus(serialNum,posBrandCode,agentid,accountNo,tid);
		} catch (DaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	@Override
	public void updateSerialNumberStatus2(String serialNum,String posBrandCode,String mid,String tid)
			throws ServiceException {
		try {
			terminalDao.updateSerialNumberStatus2(serialNum,posBrandCode,mid,tid);
		} catch (DaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	@Override
	public TblTermInf queryTermInfopart(String tid,String mid) throws ServiceException {
		TblTermInf terminfo=null;
		
		try {
			terminfo=terminalDao.queryTermInfo(tid,mid);			
		} catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("查询终端流信息关联表出错！");
		}
		
		return terminfo;
	}

	@Override
	public void bindTermTmp(TblTermInf termInf,String newCode,String posBrandCode) throws ServiceException {
		List<Object> params=new ArrayList<Object>();
		try {
			Object obj=baseDao.createSQLQueryUniqueResult("select count(*) from yj_sn_info s where s.merc_code='"+termInf.getId().getMchtCd()+"' and s.term_code='"+termInf.getId().getTermId()+"'");
			int count=Integer.parseInt(String.valueOf(obj));
			if(count==0)
			{
				params.clear();
				params.add(termInf.getId().getMchtCd());
				params.add(termInf.getId().getTermId());		
				params.add(termInf.getDeviceCd());
				params.add(newCode);
				params.add((termInf.getTmnlBrand() == null ? "" : termInf.getTmnlBrand()));
				params.add(posBrandCode);
				sqlBaseDao.deleteBySql("insert into yj_sn_info values(?,?,?,?,?,?)", params);
				logger.info("插入临时数据到yj_sn_info");				
			}
			else{
				params.clear();
				params.add(newCode);
				params.add(posBrandCode);
				params.add(termInf.getId().getMchtCd());
				params.add(termInf.getId().getTermId());
				sqlBaseDao.deleteBySql("update yj_sn_info s set s.new_sn=? ,s.NEW_POS_BRAND=? where s.merc_code=? and s.term_code=?", params);
				logger.info("更新序列号到临时表yj_sn_info");
			}
		} catch (DaoException e) {
			logger.info("更新临时表数据yj_sn_info出错!!!");
			e.printStackTrace();
		}
	}
	
	@Override
	public void sysLogRecord(String serialNum,String posBrandCode, String accountNo, String tid,String mid)
			throws ServiceException {
		try {
			baseDao.addSyslog(SysLogType.TERM_SUM.getCode(), SysLogType.TERM_SUM.getName(), accountNo, "操作员"+accountNo+"绑定终端序列号成功,商户号【"+mid+"】,终端号【"+tid+"】,序列号【"+serialNum + "-" + posBrandCode + "】");
		} catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("绑定终端序列号出错！SerialNum:"+serialNum);
		}
	}

	@Transactional
	public void delTerminalPosSNInfo(String[] sNum, Operators op)
			throws ServiceException {
		try {
			delTermiSNInfo(sNum, op);
			logger.info("操作员【" + op.getAccountNo()
					+ "】,删除SN序列号【" + Constance.getArrayStringContent(sNum) + "】信息成功");
			baseDao.addSyslog(SysLogType.SN_DELETE.getCode(),SysLogType.SN_DELETE.getName(), op.getAccountNo(), "操作员"
							+ op.getAccountNo() + " 删除 SN序列号【" + Constance.getArrayStringContent(sNum) + "】信息成功");
		} catch (DaoException e) {
			logger.error("######删除 SN 信息失败######", e);
			throw new ServiceException("删除 SN 信息失败!");
		}
	
	}
	@Transactional
	public List<String> revTerminalPosSNInfo(String[] sNum, Operators op)
			throws ServiceException {
		List<String> revSucList = new ArrayList<String>();
		try {
			 revSucList = revTermiSNInfo(sNum, op);
			if ( null != revSucList && revSucList.size() > 0 ) {
				logger.info("操作员【" + op.getAccountNo()
						+ "】,撤回SN序列号【" + revSucList.toString() + "】信息成功");
				baseDao.addSyslog(SysLogType.SN_REVOCATION.getCode(),SysLogType.SN_REVOCATION.getName(), op.getAccountNo(), "操作员"
								+ op.getAccountNo() + " 撤回 SN序列号【" + revSucList.toString() + "】信息成功");
			} 
		} catch (DaoException e) {
			logger.error("######撤回 SN 信息失败######", e);
			throw new ServiceException("撤回 SN 信息失败!");
		}
		return revSucList;
	}

	/**
	 * 
	 * @param op
	 * @param oper
	 * @param logingOperators
	 * @throws DaoException
	 */
	private void delTermiSNInfo(String[] sNum, Operators op) throws DaoException {
		for (String s : sNum) {
			String [] arr = s.split("_");
			String sn = arr[0];
			String posBrandCode = arr[1];
			// 删除 SN 关联信息
			terminalDao.delTermSNAgentInfo(sn, posBrandCode, op);
			// 删除 SN 序列号
			terminalDao.delTermSNInfo(sn, posBrandCode, op);
		}
	}

	/**
	 * 
	 * @param op
	 * @param oper
	 * @param logingOperators
	 * @throws DaoException
	 */
	private List<String>  revTermiSNInfo(String[] sNum, Operators op) throws DaoException {
		List<String> revSucList = new ArrayList<String>();
		for (String s : sNum) {
			String [] arr = s.split("_");
			String sn = arr[0];
			String posBrandCode = arr[1];
			// 撤回 SN 关联信息
			int cou = terminalDao.revTermSNAgentInfo(sn, posBrandCode, op);
			if ( cou > 0 ) {
				// 修改sn关联信息 使用状态 
				terminalDao.updTermSNAgentUsedStatus(sn, posBrandCode, op);
				revSucList.add( sn + "-"+ posBrandCode );
			} else 
				// 撤回失败
				logger.info("操作员【" + op.getAccountNo() + "】,撤回SN序列号【" + sn + "-"+ posBrandCode + "】信息失败");
		}
		return revSucList;
	}
	@Override
	public List<Map<String, Object>> superAgentId(String superAgentId) {
		Object[] parmas=new Object[1];
		parmas[0]=superAgentId;
		String sql="select id,real_name from t_operators o where  o.role_type = '03' and o.supri_id=?";
		List<Map<String, Object>> listMap=new ArrayList<Map<String,Object>>();
		try {
			List<Object> list=sqlBaseDao.queryAll(sql, parmas);
			if(list!=null&&list.size()>0)
			{
				for(int i=0;i<list.size();i++)
				{
					Map<String, Object> map=new HashMap<String, Object>();
					Object[] object=(Object[]) list.get(i);
					map.put("id", String.valueOf(object[0]));
					map.put("name", String.valueOf(object[1]));
					listMap.add(map);
				}
			}
			logger.info("加载直属代理商");
		} catch (DaoException e) {
			e.printStackTrace();
		}
		return listMap;
	}

	@Override
	@Transactional(rollbackFor={ServiceException.class})
	public synchronized void unbindTerminal(String serialNum_new,String posBrandCode,
			String mid, String tid, String accountNo)
			throws ServiceException {
		try {
		
		//获取原始序列号
		YjSnInfo yjSnInfo = terminalDao.getOriginSerialNum(mid, tid);
		logger.info("获取原始sn");
		String origin = yjSnInfo.getOriSn();
		String oldPosBrand = yjSnInfo.getOldPosBrand();
		if(null == origin || "".equals(origin))//由于切机导致的，其他平台绑定SN，本地没插入数据故需要重新插入并修改
		{
			Object[] params={mid,tid};
			String sql="select seq_device_cd.nextval from dual";
			Object objSEQ=baseDao.createSQLQueryUniqueResult(sql);
			String newSEQ="YJ"+String.valueOf(objSEQ);//生成新的序列号
			logger.info("平台切机->原始sn不存在,重新初始化SN号："+newSEQ);
			sql="from TblTermInf tt where tt.id.MchtCd=? and tt.id.TermId=?";
			TblTermInf oldTermInf=(TblTermInf)baseDao.createQueryUniqueResult(sql, params);//已绑定的序列号
			Object oldSerialNum = oldTermInf.getDeviceCd();
			Object oldBrandCode = oldTermInf.getTmnlBrand();
			
			String bindSerialNum=String.valueOf(oldSerialNum);
			String brandCode=String.valueOf(oldBrandCode);
			logger.info("切机终端SN号:"+bindSerialNum+"--切机终端厂商编号:" + brandCode);
			//插入切机终端原始SN
			sql="insert into yj_sn_info values('"+mid+"','"+tid+"','"+newSEQ+"','"+bindSerialNum+"','','" + brandCode + "')";
			int effect=sqlBaseDao.executeBySql(sql);
			if(effect>0)//执行成功
			{
				origin=newSEQ;
				oldPosBrand = "";
				logger.info("插入终端sn数据到临时表yj_sn_info成功!");
			}
		}
		//修改终端释放SN
		int rows=terminalDao.unbindTerminal(origin,serialNum_new,mid,tid, posBrandCode,oldPosBrand);
		if(rows>0)
		  {
			unbindTerminalTkey(mid, tid);
			unbindTerminalWkey(mid, tid);
			//插入系统日志信息
			baseDao.addSyslog(SysLogType.TERM_UNBUND.getCode(),SysLogType.TERM_UNBUND.getName(),accountNo,"操作员"+accountNo+"解绑终端序列号成功,商户号【"+mid+"】,终端号【"+tid+"】,序列号【"+serialNum_new + "-" + posBrandCode+"】");
			//获取SN对应所属ID
			String agentId=terminalDao.agentIDbySerialNum(serialNum_new, posBrandCode);
			//修改yj_Pos_agent
			terminalDao.unbindAgentPos(serialNum_new,agentId,accountNo,tid, posBrandCode);
			//修改yj_Pos_info
			terminalDao.unbindInfoPos(serialNum_new, posBrandCode);			
			logger.info("###########代理商【"+accountNo+"】解绑商户【"+mid+"】终端【"+tid+"】的序列号为【"+serialNum_new + "-" + posBrandCode +"】############");
		   }
		} catch (DaoException e){
			logger.debug(e.getMessage());
			throw new ServiceException("解绑终端序列号出错！SerialNum:"+serialNum_new + "-" +  posBrandCode);
		}
	}
	/**
	 * 确保同一终端同一时刻只能在一个线程中进行绑定
	 */
	@Override
	@Transactional(rollbackFor={ServiceException.class})
	public synchronized String bindTerminal(String mid,String tid,String serialNumer,String posBrandCode,Operators currentOpr,Operators loginOpr) throws ServiceException {
		String oldSerialNumber=null;
		try {
				//查询终端信息
				TblTermInf termInf=queryTermInfopart(tid, mid);
				//验证序列号是否绑定
				logger.info("验证终端是否绑定!!!");
				Pattern p=Pattern.compile("YJ[0-9]*");
				Matcher matcher = p.matcher(termInf.getDeviceCd());
				if(!matcher.matches())
				{				
					oldSerialNumber=termInf.getDeviceCd();//此时已绑定
					logger.info("终端已绑定,sn号:"+oldSerialNumber);
					return oldSerialNumber;
				}
				//为保持一致性故作修改
				logger.info("终端未绑定,可进行绑定");
				//查询序列号信息
				YjPosInfo yjPos=queryYjPosInfo(serialNumer,posBrandCode);
				bindTermTmp(termInf, serialNumer,posBrandCode);//将默认终序列号和分配序列号存入临时表
				// 修改终端表内信息
				terminalDao.setSerialNumber(tid,mid,yjPos,loginOpr.getOrgCode());				
				terminalDao.updateSerialNumberStatus(serialNumer,posBrandCode,loginOpr.getId(),currentOpr.getAccountNo(),tid);				
				terminalDao.updateSerialNumberStatus2(serialNumer,posBrandCode,mid,tid);
				sysLogRecord(serialNumer, posBrandCode, currentOpr.getAccountNo(),tid,mid);
				logger.info("###########代理商【"+currentOpr.getAccountNo()+"】绑定商户【"+mid+"】终端【"+tid+"】的序列号为【"+serialNumer + "-" + posBrandCode +"】############");
			} catch (Exception e) {
				logger.debug(e.getMessage());
				throw new ServiceException("绑定终端序列号出错!SerialNum:"+serialNumer + "-" +  posBrandCode);
			}
		return oldSerialNumber;
	}

	@Override
	public int unbindTerminalTkey(String mid, String tid)
			throws ServiceException {
		String sql="update posdbonl.tbl_term_tmk_inf set random = '000000',pub_key_data = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF',"
				+ "sec_key_data = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'"
				+ "where mcht_cd = ? and term_id = ?";
		List<Object> params=new ArrayList<Object>();
		params.add(mid);
		params.add(tid);
		try {
			sqlBaseDao.deleteBySql(sql, params);
		} catch (DaoException e) {
			logger.info("更新秘钥表posdbonl.tbl_mgm_term_tkey出错!!!");
			throw new ServiceException("更新秘钥表posdbonl.tbl_mgm_term_tkey出错!!!");
		}
		return 0;
	}

	@Override
	public int unbindTerminalWkey(String mid, String tid)
			throws ServiceException {
		String sql="update posdbonl.tbl_term_key set mac_key='FFFFFFFFFFFFFFFF',"
      +" mac_key_chk = 'FFFFFFFFFFFFFFFF',"
      +" pin_key     = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF',"
      +" pin_key_chk = 'FFFFFFFFFFFFFFFF',"
      +" trk_key     = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF',"
      +" trk_key_chk = 'FFFFFFFFFFFFFFFF'"
      +" where mcht_cd = ? and term_id = ?";
		List<Object> params=new ArrayList<Object>();
		params.add(mid);
		params.add(tid);
		try {
			sqlBaseDao.deleteBySql(sql, params);
		} catch (DaoException e) {
			logger.info("更新秘钥表posdbonl.tbl_mgm_term_wkey出错!!!");
			throw new ServiceException("更新秘钥表posdbonl.tbl_mgm_term_wkey出错!!!");
		}
		return 0;
	}

	@Override
	public int unbindYsbTerminalTkey(String mid, String tid)
			throws ServiceException {
		String sql="update posdbonl.tbl_term_tmk_inf set random = '000000',pub_key_data = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF',"
				+ "sec_key_data = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'"
				+ ", rec_upd_ts = sysdate "
				+ "where mcht_cd = ? and term_id = ?";
		
		List<Object> params=new ArrayList<Object>();
		params.add(mid);
		params.add(tid);
		try {
			sqlBaseDao.deleteBySql(sql, params);
		} catch (DaoException e) {
			logger.info("更新云商宝秘钥表posdbonl.tbl_mgm_term_tkey出错!!!");
			throw new ServiceException("更新云商宝秘钥表posdbonl.tbl_mgm_term_tkey出错!!!");
		}
		return 0;
	}

	@Override
	public int unbindYsbTerminalWkey(String mid, String tid)
			throws ServiceException {
		String sql="update posdbonl.tbl_term_key set mac_key='FFFFFFFFFFFFFFFF',"
      +" mac_key_chk = 'FFFFFFFFFFFFFFFF',"
      +" pin_key     = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF',"
      +" pin_key_chk = 'FFFFFFFFFFFFFFFF',"
      +" trk_key     = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF',"
      +" trk_key_chk = 'FFFFFFFFFFFFFFFF'"
      +", rec_upd_ts = sysdate "
      +" where mcht_cd = ? and term_id = ?";
		
		List<Object> params=new ArrayList<Object>();
		params.add(mid);
		params.add(tid);
		try {
			sqlBaseDao.deleteBySql(sql, params);
		} catch (DaoException e) {
			logger.info("更新云商宝秘钥表posdbonl.tbl_mgm_term_wkey出错!!!");
			throw new ServiceException("更新云商宝秘钥表posdbonl.tbl_mgm_term_wkey出错!!!");
		}
		return 0;
	}
	

	@Override
	@Transactional(rollbackFor={ServiceException.class})
	public synchronized void unbindYsbTerminal(String serialNum_new,String posBrandCode,
			String mid, String tid, String accountNo)
			throws ServiceException {
		try {
			TblTermInf terminal = terminalDao.queryTermInfo(tid, mid);

			String serial=terminal.getDeviceCd().trim();
			Pattern p=Pattern.compile("YJ[0-9]*");
			Matcher matcher = p.matcher(serial);
			if(matcher.matches()){
				logger.info("当前终端已解绑");
				throw new ServiceException("当前终端已解绑");
			}/*
			logger.info("检查终端可用性..");
			if("00".equals(terminal.getStatus())){
				logger.info("当前终端已冻结");
				throw new ServiceException("当前终端已冻结");
			}*/
			TPosInfo tPosInfo = new TPosInfo();
			tPosInfo.setMercCode(mid);
			tPosInfo.setTermCode(tid);
			tPosInfo.setSerialNum(serialNum_new);;
			tPosInfo.setPosBrand(posBrandCode);;
		/*	logger.info("检查交易信息...");
			Map<String, String> transPos=terminalDao.findYsbTransPos(tPosInfo);
			if("01".equals(  Constance.Null2EmptyTrim(transPos.get("wmStatus"))) ){
				if("2".equals( Constance.Null2EmptyTrim(transPos.get("wmRemark")) ) ){//携机入网需要判断是否交易
					logger.info("校验是否进行过交易..");
					//实时交易
					String transStatus=checkTransInfo(tPosInfo);
					if("Y".equals(transStatus)){
						logger.info("已存在交易记录不符合解绑条件");
						throw new ServiceException("已存在交易记录不符合解绑条件");
					}
				}else{
					logger.info("已存在交易记录不符合解绑条件");
					throw new ServiceException("已存在交易记录不符合解绑条件");
				}
			}		
			
*/
			logger.info("准备解绑..");
			Date date=new Date();
			logger.info("更新代理商SN关系..");
	//		String maxUpdDate=terminalDao.selectYsbMaxAgent(tPosInfo);
	//		tPosInfo.setMaxUpdDate(maxUpdDate);
			//修改t_pos_agent
			tPosInfo.setIsUsed("N");
			terminalDao.updateYsbPosAgent(tPosInfo);
			//修改t_pos_info
			logger.info("更新SN信息..");
			terminalDao.unboundYsbPosInfo(tPosInfo);
			//销毁商户终端关系去掉
			//修改终端
			unboundSn(tPosInfo, date,accountNo);
			//剔除完美账单的数据
			terminalDao.dealWMRecord(tPosInfo);

			logger.info("检查D0费率是否存在...");
			int fee_count = terminalDao.selectYsbD0FeeInfo( tPosInfo);
			//剔除D0费率的数据
			if ( fee_count > 0 ) {
				logger.info("剔除D0费率的数据...");
				terminalDao.dealYsbD0FeeInfo( tPosInfo);
			}

			logger.info("检查D0产品是否存在...");
			int pro_count = terminalDao.selectYsbD0ProductInfo( tPosInfo);
			//剔除D0产品的数据
			if ( pro_count > 0 ) {
				logger.info("剔除D0产品的数据...");
				terminalDao.dealYsbD0ProductInfo( tPosInfo);
			}

			logger.info("检查核心D0产品是否存在...");
			int hx_pro_count = terminalDao.selectYsbHxD0ProductInfo( tPosInfo);
			//剔除核心D0产品的数据
			if ( hx_pro_count > 0 ) {
				logger.info("剔除核心D0产品的数据...");
				terminalDao.dealYsbHxD0ProductInfo( tPosInfo);
			}

			logger.info("销毁当天T1历史费率...");
			//销毁当天D0费率
			terminalDao.dealYsbT1HisFeeInfo(tPosInfo);

			logger.info("更新云商宝T1借记卡费率...");
			//更新云商宝T1借记卡费率
			terminalDao.updYsbT1FeeByFeeCd("0.58", "22.0", tPosInfo.getMercCode(), "0001000");;

			logger.info("更新云商宝T1贷记卡费率...");
			//更新云商宝T1贷记卡费率
			terminalDao.updYsbT1FeeByFeeCd("0.58", "0.0", tPosInfo.getMercCode(), "0001001");;
			
			//销毁原有主密钥、pinkey,mackey
			logger.info("销毁原有主密钥..");
			unbindYsbTerminalTkey(mid, tid);
			logger.info("销毁原有PINKEY和MACKEY..");
			unbindYsbTerminalWkey(mid, tid);
			logger.info("解绑成功");
		} catch (DaoException e){
			logger.debug(e.getMessage());
			throw new ServiceException("解绑云商宝终端序列号出错！SerialNum:"+serialNum_new + "-" +  posBrandCode);
		}
	}

	@Override
	public String queryYsbDirAgentByTerm(TPosInfo tPosInfo) throws ServiceException {
		String agentId = null;
		try {
			agentId=terminalDao.selectYsbDirAgentByTerm(tPosInfo);			
		} catch (DaoException e) {
			logger.debug(e.getMessage());
			throw new ServiceException("查询SN关系表直属代理商id出错！");
		}
		
		return agentId;
	}
	

	@Override
	@Transactional(rollbackFor={ServiceException.class})
	public synchronized String replaceYsbTerminal(String serialNum_new,String posBrandCode_new,String posModelNo_new, String mid, String tid,String dirAgentId,Operators loginOpr)
			throws ServiceException {
		String msg = "";
		try {
			TblTermInf terminal = terminalDao.queryTermInfo(tid, mid);

			String old_serial = terminal.getDeviceCd().trim();
			String old_posBrandCode = terminal.getTmnlBrand();
			String old_posModelNo = terminal.getTmnlModelNo();
			Pattern p=Pattern.compile("YJ[0-9]*");
			Matcher matcher = p.matcher(old_serial);
			if(matcher.matches()){
				msg = "旧机器终端已解绑";
				logger.info("旧机器终端已解绑");
				return msg;
			//	throw new ServiceException("旧机器终端已解绑");
			}
			TPosInfo bean = new TPosInfo();
			bean.setSerialNum(serialNum_new);
			bean.setPosBrand(posBrandCode_new);
			bean.setAgentId(Long.valueOf(dirAgentId));
			TPosInfo info = terminalDao.selectYsbSnInfoByAgent(bean);
			
			if(null == info || info.getIsBind().equals("Y") || info.getIsUsed().equals("Y")){
				msg = "新机器终端不属于此直属代理商或已绑定或已分配";
				logger.info("新机器终端不属于此直属代理商或已绑定或已分配");
				return msg;
			//	throw new ServiceException("新机器终端不属于此直属代理商或已绑定或已分配");
			}
			/*
			logger.info("检查终端可用性..");
			if("00".equals(terminal.getStatus())){
				logger.info("当前终端已冻结");
				throw new ServiceException("当前终端已冻结");
			}*/
			TPosInfo tPosInfo = new TPosInfo();
			tPosInfo.setMercCode(mid);
			tPosInfo.setTermCode(tid);
			tPosInfo.setSerialNum(old_serial);
			tPosInfo.setPosBrand(old_posBrandCode);
		
			logger.info("准备换机..");
			logger.info("解绑旧机器..");
			Date date=new Date();
			logger.info("----更新代理商SN关系..");
			//修改t_pos_agent
			tPosInfo.setIsUsed("N");
			terminalDao.updateYsbPosAgent(tPosInfo);
			//修改t_pos_info
			logger.info("----更新SN信息..");
			terminalDao.unboundYsbPosInfo(tPosInfo);
			
			
			logger.info("绑定新机器..");
			TPosInfo tPosInfoNew = new TPosInfo();
			tPosInfoNew.setMercCode(mid);
			tPosInfoNew.setTermCode(tid);
			tPosInfoNew.setSerialNum(serialNum_new);;
			tPosInfoNew.setPosBrand(posBrandCode_new);;

			logger.info("----更新代理商SN关系..");
			//修改t_pos_agent
			tPosInfoNew.setIsUsed("Y");
			terminalDao.updateYsbPosAgent(tPosInfoNew);
			//修改t_pos_info
			logger.info("----更新SN信息..");
			tPosInfoNew.setIsBind("Y");
			terminalDao.boundYsbPosInfo(tPosInfoNew);
						
			//修改商户终端关系
			//修改终端
			tPosInfoNew.setPosName(posModelNo_new);
			replaceSn(tPosInfoNew, date,loginOpr.getAccountNo(),old_serial,old_posBrandCode);
			//添加 换机记录表的数据
			TPosReplace posReplace = new TPosReplace();
			posReplace.setMerNo(mid);
			posReplace.setOldserialNum(old_serial);
			posReplace.setNewserialNum(serialNum_new);
			posReplace.setOperateDate(DateTime.getNow("yyyyMMddHHmmss"));
			posReplace.setOldbrandNo(old_posBrandCode);
			posReplace.setOldmodelNo(old_posModelNo);
			posReplace.setNewbrandNo(posBrandCode_new);
			posReplace.setNewmodelNo(posModelNo_new);
			posReplace.setOperId(loginOpr.getAccountNo());
			terminalDao.insertTPosReplace(posReplace);
			//销毁原有主密钥、pinkey,mackey
			logger.info("销毁原有主密钥..");
			unbindYsbTerminalTkey(mid, tid);
			logger.info("销毁原有PINKEY和MACKEY..");
			unbindYsbTerminalWkey(mid, tid);
			logger.info("换机成功");
			msg = "云商宝终端换机成功！SerialNum:"+serialNum_new + "-" +  posBrandCode_new;
		} catch (DaoException e){
			logger.debug(e.getMessage());
			throw new ServiceException("云商宝终端换机出错！SerialNum:"+serialNum_new + "-" +  posBrandCode_new);
		}
		return msg;
	}
	/**
	 * 检查交易信息
	 * @param posInfo
	 * @return
	 */
	protected String checkTransInfo(TPosInfo posInfo) throws DaoException{
		String status="N";
		try { 
			logger.info("校验实时交易信息..");
			int count=terminalDao.selectYsbTransInfo(posInfo);
			if(count>0){
				status="Y";
			}else{
				logger.info("校验15日交易信息..");
				count=terminalDao.selectYsbFifteenTransInfo(posInfo);
				if(count>0){
					status="Y";
				}else{
					logger.info("校验历史交易信息..");
					count=terminalDao.selectYsbHistoryTransInfo(posInfo);
					if(count>0){
						status="Y";
					}
				}
			}
		} catch (DaoException e){
			logger.debug(e.getMessage());
			throw new DaoException("校验交易信息出错");
		}
		return status;
	}

	/**
	 * 解绑终端
	 * @param posInfo
	 * @param date
	 * @param sn
	 */
	protected void unboundSn(TPosInfo tPosInfo,Date date,String accountNo/*,MiddleSn sn*/) throws DaoException{
		try { 
		logger.info("释放云商宝终端..");		
		baseDao.addSyslog(SysLogType.YSB_TERM_UNBUND.getCode(),SysLogType.YSB_TERM_UNBUND.getName(),accountNo,"操作员"+accountNo+"解绑终端序列号成功,商户号【"+tPosInfo.getMercCode()+"】,终端号【"+tPosInfo.getTermCode()+"】,序列号【"+tPosInfo.getSerialNum() + "-" + tPosInfo.getPosBrand()+"】");
		
		String ori=terminalDao.queryExistSn(tPosInfo);

		if( ori != null && !"".equals(ori) ){
			tPosInfo.setSerialNum(ori);
		}else{
			int origin=terminalDao.serialNumGenerator(tPosInfo);
			String newSerialNum="YJ"+String.valueOf(origin);
			YjSnInfo newSn=new YjSnInfo();
			newSn.setMercCode(tPosInfo.getMercCode());	
			newSn.setTermCode(tPosInfo.getTermCode());
			newSn.setOriSn(newSerialNum);
			newSn.setNewSn(tPosInfo.getSerialNum());
			newSn.setNewPosBrand(tPosInfo.getPosBrand());

			terminalDao.insertSnInfo(newSn);
			tPosInfo.setSerialNum(newSerialNum);
		}
		tPosInfo.setPosBrand(null);
		tPosInfo.setPosName(null);
		terminalDao.unboundTerminal(tPosInfo);

	} catch (DaoException e){
		logger.debug(e.getMessage());
		throw new DaoException("释放云商宝终端出错");
	}
	}

	/**
	 * 终端换机
	 * @param posInfo
	 * @param date
	 * @param sn
	 */
	protected void replaceSn(TPosInfo tPosInfo,Date date,String accountNo,String old_serial,String old_posBrandCode) throws DaoException{
		try { 
		logger.info("云商宝终端换机..");		
		baseDao.addSyslog(SysLogType.YSB_TERM_REPLACE.getCode(),SysLogType.YSB_TERM_REPLACE.getName(),accountNo,"操作员"+accountNo+"换机成功,商户号【"+tPosInfo.getMercCode()+"】,终端号【"+tPosInfo.getTermCode()+"】,由终端序列号【"+old_serial + "-" + old_posBrandCode+"】 换为终端序列号【"+tPosInfo.getSerialNum() + "-" + tPosInfo.getPosBrand()+"】");
		
		String ori=terminalDao.queryExistSn(tPosInfo);

		// 如果原始SN记录表内有数据，将新的SN改为换机后的Sn
		if( ori != null && !"".equals(ori) ){
			YjSnInfo newSn=new YjSnInfo();
			newSn.setMercCode(tPosInfo.getMercCode());	
			newSn.setTermCode(tPosInfo.getTermCode());
			newSn.setNewSn(tPosInfo.getSerialNum());
			newSn.setNewPosBrand(tPosInfo.getPosBrand());
			terminalDao.updateSnInfo(newSn);
		}else{
			int origin=terminalDao.serialNumGenerator(tPosInfo);
			String newSerialNum="YJ"+String.valueOf(origin);
			YjSnInfo newSn=new YjSnInfo();
			newSn.setMercCode(tPosInfo.getMercCode());	
			newSn.setTermCode(tPosInfo.getTermCode());
			newSn.setOriSn(newSerialNum);
			newSn.setNewSn(tPosInfo.getSerialNum());
			newSn.setNewPosBrand(tPosInfo.getPosBrand());

			terminalDao.insertSnInfo(newSn);
		}
		terminalDao.replaceTerminal(tPosInfo);

	} catch (DaoException e){
		logger.debug(e.getMessage());
		throw new DaoException("云商宝终端换机出错");
	}
	}

	@Transactional
	public List<String> revYsbTerminalPosSNInfo(TPosAgent tPosAgent, Operators op)
			throws ServiceException {
		Map<String, String> existsMap = new HashMap<String, String>();
		List<String> noExistsList = new ArrayList<String>();
		try { //String[] sNum 

			String beginSn = Utils.changeCharUpperCase( tPosAgent.getBeginSerialNum() );
			String endSn = Utils.changeCharUpperCase( tPosAgent.getEndSerialNum() );
			int nums = tPosAgent.getNums();
			// 取SN最后一个字符的位置,便于分割
			int bLastChar = Constance.getSNLastCharPlace(beginSn);

			String bChars = getChar(bLastChar, beginSn);
			String bNumber = getSnNumber(bLastChar, beginSn);
			Long number = -1l;
			if( null != bNumber && !"".equals( bNumber )) {
				number = Long.parseLong( bNumber );
			}
			int zeroLength = beginSn.length() - bChars.length() - String.valueOf( number ).length();
			for ( int s = 1; s <= nums; s++) {
				Long lastNumber = number - 1;
				
				if( String.valueOf( number ).length() > String.valueOf( lastNumber ).length() ) {
					zeroLength = zeroLength - 1;
				}
				String serialNum = bChars ;
				if ( number != -1l ) {
					serialNum = serialNum + Utils.addLeftZero(zeroLength, number);
				}
				String sn = Utils.changeCharUpperCase( serialNum );
				String posBrandCode = tPosAgent.getPosBrand();
				// 查询此 云商宝SN 是否属于此登录账号
				String asset_flag = terminalDao.queryRevSnByAgentId(sn, posBrandCode, op);
				if  ( null != asset_flag && !"".equals(asset_flag) ) 
					existsMap.put(sn, asset_flag);
				else noExistsList.add(sn);

				number++;
			}
			if ( null != existsMap && 0 < existsMap.size() ) {
				revYsbTermiSNInfo(existsMap,tPosAgent.getPosBrand(), op);
				logger.info("操作员【" + op.getAccountNo()
					+ "】,撤回云商宝SN序列号【" + existsMap.keySet().toString() + "-" + tPosAgent.getPosBrand() + "】信息成功");
				baseDao.addSyslog(SysLogType.YSB_SN_REVOCATION.getCode(),SysLogType.YSB_SN_REVOCATION.getName(), op.getAccountNo(), "操作员"
							+ op.getAccountNo() + " 撤回 云商宝SN序列号【" + existsMap.keySet().toString() + "-" + tPosAgent.getPosBrand() + "】信息成功");
			} else 
				logger.info("##########操作员【"+op.getAccountNo()+"】撤回云商宝SN序列号【"+noExistsList.toString() 
								+ "-" + tPosAgent.getPosBrand() + "】时未找到/未分配/已绑定/不存在，不处理##########");
			
		} catch (DaoException e) {
			logger.error("######撤回 云商宝SN 信息失败######", e);
			throw new ServiceException("撤回 云商宝SN 信息失败!");
		}
		return noExistsList;
	}

	/**
	 * 
	 * @param op
	 * @param oper
	 * @param logingOperators
	 * @throws DaoException
	 */
	private void revYsbTermiSNInfo(Map<String, String> existsMap,String posBrandCode, Operators op) throws DaoException {
		for (String sn : existsMap.keySet()) {
			// 撤回 云商宝SN 关联信息
			terminalDao.revYsbTermSNAgentInfo(sn, posBrandCode,existsMap.get(sn), op);
			// 修改云商宝sn关联信息 使用状态 
			terminalDao.updYsbTermSNAgentUsedStatus(sn, posBrandCode, op);
		}
	}

	private String getChar( int lastChar ,String sn ){
		String bChars = "";
		if( lastChar >= 0){
			bChars = sn.substring(0, lastChar + 1);
		}
		return bChars;
	}

	private String getSnNumber( int lastChar ,String sn ){
		String bNumber = "";
		if ( lastChar < ( sn.length()-1 ) ){
			bNumber = sn.substring( ( lastChar== -1 ? 0 : lastChar + 1 ), sn.length() );
		}
		return bNumber;
	}
	
}
